/* 
 * Copyright (C) 2014 Ningbo Yuanqun Inc., All Rights Reserved. 
 */
package com.yuanqunsoft.alimigration.common;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

/**
 * <p>
 * 解析JSON的第三方依赖包是Jackson-Json， 详情请参考<a href="https://github.com/FasterXML/jackson-databind">Jackson-databind
 * Github主页</a>
 * </p>
 * 
 * @author ShaoYu
 * @version 1.0
 */
public final class JSONUtil {

    private static Logger logger = LogManager.getLogger(JSONUtil.class);

    private JSONUtil() {

    }

    /**
     * <p>
     * 将一个对象转为JSON形式的表示
     * </p>
     * 
     * @param obj
     *            待转换的对象
     * @return
     */
    public static String objToStr(Object obj) {
        Helper.checkNull(obj, "obj");
        ObjectMapper mapper = new ObjectMapper();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            logger.error(e);
            e.printStackTrace();
            return null;
        }
    }

    /**
     * <p>
     * 将一个JSON格式的字符串转为指定类型的实例
     * </p>
     * 
     * @param json
     *            待转化的JSON字符串
     * @param clazz
     *            转换的实例类型
     * @return
     */
    public static <T> T strToObj(String json, Class<T> clazz) {
        Helper.checkStringNullorEmpty(json, "json");
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(json, clazz);
        } catch (IOException e) {
            logger.error(e);
            e.printStackTrace();
            return null;
        }
    }

    /**
     * <p>
     * 将一个JSON格式的字符串转为指定类型的实例
     * </p>
     * 
     * @param src
     *            包含待转化的JSON字符串的文件
     * @param clazz
     *            转换的实例类型
     * @return
     */
    public static <T> T strToObj(File src, Class<T> clazz) {
        Helper.checkNull(src, "src");
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(src, clazz);
        } catch (IOException e) {
            logger.error(e);
            e.printStackTrace();
            return null;
        }
    }

    /**
     * <p>
     * 将一个JSON字符串转为指定泛型的List（默认为ArrayList）
     * </p>
     * 
     * @param json
     *            待转化的JSON字符串
     * @param clazz
     *            转换的List的泛型参数类型
     * @return
     */
    public static <T> List<T> strToList(String json, Class<T> clazz) {
        Helper.checkStringNullorEmpty(json, "json");
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(json, mapper.getTypeFactory().constructParametricType(ArrayList.class, clazz));
        } catch (IOException e) {
            logger.error(e);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * <p>
     * 将一个JSON字符串转为指定泛型的List（默认为ArrayList）
     * </p>
     * 
     * @param src
     *            包含待转化的JSON字符串的文件
     * @param clazz
     *            转换的List的泛型参数类型
     * @return
     */
    public static <T> List<T> strToList(File src, Class<T> clazz) {
        Helper.checkNull(src, "src");
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(src, mapper.getTypeFactory().constructParametricType(ArrayList.class, clazz));
        } catch (IOException e) {
            logger.error(e);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * <p>
     * 将一个JSON字符串转为指定泛型的Set（默认为HashSet）
     * </p>
     * 
     * @param json
     *            待转化的JSON字符串
     * @param clazz
     *            转换的List的泛型参数类型
     * @return
     */
    public static <T> Set<T> strToSet(String json, Class<T> clazz) {
        Helper.checkStringNullorEmpty(json, "json");
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(json, mapper.getTypeFactory().constructParametricType(HashSet.class, clazz));
        } catch (IOException e) {
            logger.error(e);
            e.printStackTrace();
        }
        return null;
    }

    /**
     * <p>
     * 将一个JSON字符串转为指定泛型的Set（默认为HashSet）
     * </p>
     * 
     * @param src
     *            包含待转化的JSON字符串的文件
     * @param clazz
     *            转换的List的泛型参数类型
     * @return
     */
    public static <T> Set<T> strToSet(File src, Class<T> clazz) {
        Helper.checkNull(src, "src");
        ObjectMapper mapper = new ObjectMapper();
        try {
            return mapper.readValue(src, mapper.getTypeFactory().constructParametricType(HashSet.class, clazz));
        } catch (IOException e) {
            logger.error(e);
            e.printStackTrace();
        }
        return null;
    }
}
